const jwt = require('jsonwebtoken');
const User = require('../models/user');
const jwtConfig = require('../config/jwt');
require('dotenv').config();

// 认证中间件 - 验证访问令牌
const authenticateToken = async (ctx, next) => {
  try {
    // 从请求头获取令牌
    const authHeader = ctx.headers.authorization;
    const token = authHeader && authHeader.split(' ')[1];

    if (!token) {
      ctx.status = 401;
      ctx.body = {
        error: '未提供访问令牌',
        message: '请在请求头中提供有效的Bearer令牌'
      };
      return;
    }

    // 验证令牌
    let decoded;
    try {
      decoded = jwt.verify(token, jwtConfig.secret);
    } catch (jwtError) {
      ctx.status = 401;
      ctx.body = {
        error: '无效的令牌',
        message: jwtError.name === 'TokenExpiredError' ? '令牌已过期' : '令牌验证失败'
      };
      return;
    }

    // 查找用户
    const user = await User.findById(decoded.userId);
    if (!user) {
      ctx.status = 401;
      ctx.body = {
        error: '用户不存在',
        message: '令牌关联的用户不存在'
      };
      return;
    }

    // 检查用户状态
    if (user.status !== 'active') {
      ctx.status = 403;
      ctx.body = {
        error: '用户已禁用',
        message: '您的账户已被禁用，请联系管理员'
      };
      return;
    }

    // 将用户信息添加到上下文
    ctx.user = {
      id: user._id,
      username: user.username,
      email: user.email,
      name: user.name,
      role: user.role,
      phone: user.phone
    };

    await next();
  } catch (error) {
    console.error('认证中间件错误:', error);
    ctx.status = 500;
    ctx.body = {
      error: '服务器错误',
      message: '认证过程中发生错误'
    };
  }
};

// 角色验证中间件
const authorizeRole = (roles) => {
  if (!Array.isArray(roles)) {
    roles = [roles];
  }

  return async (ctx, next) => {
    if (!ctx.user) {
      ctx.status = 401;
      ctx.body = {
        error: '未认证',
        message: '请先进行身份认证'
      };
      return;
    }

    if (!roles.includes(ctx.user.role)) {
      ctx.status = 403;
      ctx.body = {
        error: '权限不足',
        message: '您没有权限访问此资源'
      };
      return;
    }

    await next();
  };
};

// 刷新令牌中间件 - 用于验证刷新令牌
const authenticateRefreshToken = async (ctx, next) => {
  try {
    // 从请求体获取刷新令牌
    const { refreshToken } = ctx.request.body;

    if (!refreshToken) {
      ctx.status = 401;
      ctx.body = {
        error: '未提供刷新令牌',
        message: '请在请求体中提供有效的刷新令牌'
      };
      return;
    }

    // 这里应该从数据库中验证刷新令牌
    // 由于我们的模型中包含了refreshToken，应该从那里查询
    const user = await User.findOne({
      refreshTokens: refreshToken
    });

    if (!user) {
      ctx.status = 401;
      ctx.body = {
        error: '无效的刷新令牌',
        message: '刷新令牌不存在或已过期'
      };
      return;
    }

    // 验证刷新令牌的有效性
    let decoded;
    try {
      decoded = jwt.verify(refreshToken, jwtConfig.secret);
    } catch (jwtError) {
      ctx.status = 401;
      ctx.body = {
        error: '无效的刷新令牌',
        message: '刷新令牌已过期或无效'
      };
      return;
    }

    // 将用户信息添加到上下文
    ctx.user = {
      id: user._id,
      username: user.username,
      email: user.email,
      name: user.name,
      role: user.role,
      phone: user.phone
    };

    await next();
  } catch (error) {
    console.error('刷新令牌认证中间件错误:', error);
    ctx.status = 500;
    ctx.body = {
      error: '服务器错误',
      message: '刷新令牌认证过程中发生错误'
    };
  }
};

module.exports = {
  authenticateToken,
  authorizeRole,
  authorize: authorizeRole, // 添加别名以兼容现有代码
  authenticateRefreshToken
};